feat(usage): enforce one free account per install (fair-use policy) - #159
feat(usage): enforce one free account per install (fair-use policy)#159Fahad090NP wants to merge 4 commits into
Conversation
|
If I ever had a wish for any of my PR to be approved, then this is the one. Not because I am jealous of the people who are using this trick to scam OpenCode and I am not, but because both Islam and then the ethics forbids such acts strictly. It was always be a difficult thing to let others think what I actually want to say. Fi Amanillah. |
|
I do not want to hear anything other than any bug or inconsistency in my code. Either Merge, tell me what to improve, or Reject it. |
|
@Fahad090NP, thanks for this. I read through it twice and I'll give you the straight answer you asked for. The code itself is clean. The pure module split, the 11 tests, the honest limitations section, it's better put together than most PRs I get here. I also understand the motivation and I respect it. But I'm going to reject this one, and you asked for bugs and inconsistencies, so here they are. The first one is serious: it contradicts a feature we shipped about five weeks ago. Issue #63 and PR #75 added multi-account profile support because people have legitimate reasons to hold multiple keys. A work account and a personal one. Teams where every developer runs their own Go subscription. One account with keys spread across machines. Your policy counts accounts by key fingerprint, so those users walk straight into the block.
There's also a state leak. Remove a BYOK entry through the VS Code Manage panel instead of our Delete Profile command and the fingerprint stays in the policy storage. Nothing clears it unless they happen to run Delete Profile on that exact profile. Blocked, with no obvious way out. I could ask you to fix the fingerprint handling. Even fixed, the deeper problem stays: the rule itself doesn't exist. I checked OpenCode's Terms of Use and the Zen docs before writing this. There is no one-free-account-per-person policy anywhere. The free models are a limited-time feedback program, and the ToS explicitly leaves violation decisions to OpenCode. Shipping this means enforcing a rule we invented on their behalf, and the error message reads "OpenCode free-account limit reached". Someone hits that at midnight, reads it, and walks away thinking OpenCode blocked them when it was our extension. That turns into bug reports I can't do anything about. And since the rule is invented, check who it actually catches. Anyone harvesting quota can use the CLI, another machine, or a separate VS Code profile, since globalState doesn't cross profiles. The ones who hit the wall are the legitimate multi-account users above. If OpenCode wants fair-use enforcement, they have the identity and billing data server-side to do it right. That's where this belongs, not in a client. If you want to keep pushing the idea, the version I'd merge is a non-blocking warning: a status-bar hint when multiple free fingerprints are detected, no request blocking. Tell the user, let them decide. One more thing, about the comment you left below. I read it, and I want to answer part of it. This PR doesn't get merged, but the intention behind it, protecting something you believe is right and refusing to look away from what you see as wrong, is already recorded by Allah. May He accept it as a good deed for you. That intention counts for more than the code. Hope to see more PRs from you on other things. Jazakallah Khair. |
📝 What does this change?
A single-free-account fair-use policy so one person can't harvest OpenCode's free quota by registering multiple free accounts (inference is expensive for everyone).
The rule: exactly one free account is allowed per install. The moment 2+ free accounts are detected, free-model usage is blocked with a clear, actionable error. Paid usage is never blocked — multiple paid accounts are fine. Delete down to 1 free account (or make the extra one paid) and free models work again.
How an account is classified (per API-key fingerprint):
*-free/big-pickle)./zen/go/v1/usageendpoint) or successfully uses a paid model → exempt from the free limit.Coverage: new profiles and existing profiles (re-evaluated on every request), the Agents window, and vision-proxy requests. The block fires before the request is sent, so no quota is spent.
Code structure (4 commits, pure-logic separation):
src/usage/freeAccountPolicy.ts+ storage wrapper + 11 unit tests (src/test/freeAccountPolicy.test.ts) covering: single free allowed, 2nd free blocks, paid exemption, lapsed-sub re-classification, TTL renewal, delete-account recovery, round-trip persistence.provideLanguageModelChatResponse(+ paid confirmation on successful paid-model usage).Delete Profilecleans the policy; the Usage quick-pick warns when free usage is blocked; Diagnostics now shows a "Free-Account Policy" section (free/paid fingerprints + blocked state) so the policy is transparent.🧪 How did you test it?
npm run lint— all 7 steps green, incl. the 11 new policy unit tests.✅ Checklist
npm run compilepassesnpm run lintpassesnpm testpassesnpm run packageproduces a VSIX (not run — code + tests only)